import axios from 'axios'
import { authorizationValue } from '@/setting'
// import store from '@/store/index'
import router from '@/router'
import { getToken, getRefreshToken, getExpireTime } from '@/utils/auth'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
// 自定义api
const api = require('@/api');
// 请求超时时间，30s
const requestTimeOut = 30 * 1000
// 响应状态码
const success = 200
// 更换令牌的时间区间 5分钟
const checkRegion = 5 * 60 * 1000
// 提示信息显示时长 5秒
const messageDuration = 5 * 1000

// 系统全局请求对象(axios实例)
const service = axios.create({
    baseURL: process.env.VUE_APP_BASE_API,
    timeout: requestTimeOut,
    responseType: 'json',
    validateStatus(status) {
        return status === success
    }
})

// 系统令牌刷新请求对象
const refresh_service = axios.create({
    baseURL: process.env.VUE_APP_BASE_API,
    timeout: requestTimeOut,
    responseType: 'json',
    validateStatus(status) {
        return status === success
    }
})

// 请求拦截器
// 主要是为了在请求发出去之前，添加token和header
// service.interceptors.request.use(
//     config => {
//         let _config = config
//         try {
//             // 获取当前缓存token的有效时长
//             const expireTime = getExpireTime()
//             if (expireTime) {
//                 // 如果存在，则计算剩余时间
//                 const left = expireTime - new Date().getTime()
//                 // 获取当前缓存的刷新令牌
//                 const refreshToken = getRefreshToken()
//                 // checkRegion：更换令牌的时间区间
//                 // 如果剩余时间小于需要更换令牌的时间并且能获取到本地缓存的刷新令牌，那么就到后台请求一个新的令牌
//                 if (left < checkRegion && refreshToken) {
//                     _config = queryRefreshToken(_config, refreshToken)
//                 } else {
//                     // 如果不需要刷新本地缓存令牌
//                     if (getToken()) {
//                         // 直接将本地缓存的令牌拿来用
//                         _config.headers['Authorization'] = 'bearer ' + getToken()
//                     }
//                 }
//             }
//         } catch (e) {
//             console.error(e)
//         }
//         return _config
//     },
//     error => {
//         console.log(error)
//         return Promise.reject(error)
//     }
// )

/**
 * 请求响应拦截器
 *
 */
service.interceptors.response.use(
    // 如果成功，直接返回
    (config) => {
                     return config
    },
    (error) => {
        // 如果请求失败，对各种可能的情况进行处理
    if (error.response) {
        const errorMessage = error.response.data === null ? this.$t('system.error') : error.response.data.message
        switch (error.response.status) {
            case 404:
                this.$message.error(this.$t('system.not_found'))
                break
            case 403:
                this.$message.error(this.$t('system.hasNoPermission'))
                break
            case 401:
                // router.push('/login')
                this.$message.error(this.$t('system.login_expired'))
                break
            default:
                if (errorMessage === 'refresh token无效') {
                    // router.push('/login')
                  this.$message.error(this.$t('system.login_expired'))
                } else {
                  this.$message.error(this.$t('system.not_found'))
                }
                break
        }
    }
    if (error.message.includes('timeout')) {
      this.$message.error(this.$t('system.request_timeout'))
    }
    return Promise.reject(error)
})

const request = {
    refresh(url, params) {
        params['grant_type'] = 'refresh_token'
        return refresh_service.post(url, params, {
            transformRequest: [(params) => {
                return tansParams(params)
            }],
            headers: {
                'Authorization': authorizationValue
            }
        })
    },
    login(url, params) {
        params['grant_type'] = 'password'
        return service.post(url, params, {
            transformRequest: [(params) => {
                return tansParams(params)
            }],
            headers: {
                'Authorization': authorizationValue
            }
        })
    },
    post(url, params) {
        console.log(api[url]);
        return service.post(api[url], params, {
            headers: {
                'Content-Type': 'application/json'
            }
        })
    },
    get(url, params) {
        let _params
        if (Object.is(params, undefined)) {
            _params = ''
        } else {
            _params = '?'
            for (const key in params) {
                // eslint-disable-next-line no-prototype-builtins
                if (params.hasOwnProperty(key) && params[key] !== null) {
                    _params += `${key}=${params[key]}&`
                }
            }
        }
        return service.get(api[url]+`${_params}`)
    },
    download(url, params, filename) {
        NProgress.start()
        return service.post(url, params, {
            transformRequest: [(params) => {
                return tansParams(params)
            }],
            responseType: 'blob'
        }).then((r) => {
            const content = r.data
            const blob = new Blob([content])
            if ('download' in document.createElement('a')) {
                const elink = document.createElement('a')
                elink.download = filename
                elink.style.display = 'none'
                elink.href = URL.createObjectURL(blob)
                document.body.appendChild(elink)
                elink.click()
                URL.revokeObjectURL(elink.href)
                document.body.removeChild(elink)
            } else {
                navigator.msSaveBlob(blob, filename)
            }
            NProgress.done()
        }).catch((r) => {
            console.error(r)
            NProgress.done()
            this.$message.error(this.$t('system.download_fail'))
        })
    },
    upload(url, params) {
        return service.post(url, params, {
            headers: {
                'Content-Type': 'multipart/form-data'
            }
        })
    }
}

function tansParams(params) {
    let result = ''
    Object.keys(params).forEach((key) => {
        if (!Object.is(params[key], undefined) && !Object.is(params[key], null)) {
            result += encodeURIComponent(key) + '=' + encodeURIComponent(params[key]) + '&'
        }
    })
    return result
}

/**
 * 获取刷新令牌 注意是同步请求
 *
 * @param config
 * @param refreshToken
 * @returns {Promise<*>}
 */
async function queryRefreshToken(config, refreshToken) {
    const result = await request.refresh('auth/oauth/token', {
        refresh_token: refreshToken
    })
    // 如果请求成功
    if (result.status === success) {
        // 保存数据道本地
        // saveData(result.data)
        // 给请求头设置token
        config.headers['Authorization'] = 'bearer ' + getToken()
    }
    return config
}

// function saveData(data) {
//     store.commit('account/setAccessToken', data.access_token)
//     store.commit('account/setRefreshToken', data.refresh_token)
//     const current = new Date()
//     const expireTime = current.setTime(current.getTime() + 1000 * data.expires_in)
//     store.commit('account/setExpireTime', expireTime)
// }

export default request
